from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from django.db.models import F
from django.http import JsonResponse
import json

from app import models
from app.models import student, course as CourseModel, chco
from pyecharts import options as opts
from pyecharts.charts import Line
from pyecharts.globals import ThemeType
from rest_framework.views import APIView
from pyecharts.charts import Bar


# Create your views here.
@csrf_exempt
def login(request):
    tip = "请进行登录"
    if request.method == 'POST':
        username = request.POST['user']  # 获取学号
        password = request.POST['pwd']  # 获取密码
        if username == "" or password == "":  # 验证学号,密码是否为空
            tip = "学号或密码不能为空"
            return render(request, 'login.html', {'tip': tip})  # 登录失败，返回登录页面

        # 判断学号是否存在
        if student.objects.filter(stu_num=username):  # 存在
            user = student.objects.get(pk=username)  # 获取用户信息
            if user.stu_pwd == password:  # 验证密码
                # 注册用户信息到会话
                request.session['username'] = username
                request.session['stu_name'] = user.stu_name
                request.session['stu_zhuanye'] = user.stu_zhuanye
                request.session['stu_sex'] = user.stu_sex
                request.session['is_authenticated'] = True
                return redirect('/index')  # 登录成功，返回首页接口
            else:
                tip = "密码错误"
                return render(request, 'login.html', {'tip': tip})
        else:
            tip = "学号不存在"
            return render(request, 'login.html', {'tip': tip})

    return render(request, 'login.html', {'tip': tip})


def index(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')

    try:
        # 从会话中获取用户名并查询完整的学生信息
        username = request.session.get('username')
        stuinfo = models.student.objects.get(pk=username)
        return render(request, 'index.html', {'stuinfo': stuinfo})
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


def course(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')

    try:
        # 获取当前登录学生的学号
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)

        # 查询该学生选择的所有课程
        # 通过选课表关联学生和课程
        courses = []
        course_choices = models.chco.objects.filter(chco_st=student_obj)

        for choice in course_choices:
            courses.append(choice.chco_co)

        return render(request, 'course.html', {'courses': courses})
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


# @csrf_exempt
# def add_course(request):
#     # 检查用户是否已登录
#     if not request.session.get('is_authenticated'):
#         return redirect('/login')
#
#     try:
#         # 获取当前登录学生信息
#         username = request.session.get('username')
#         student_obj = models.student.objects.get(pk=username)
#
#         if request.method == 'POST':
#             # 获取用户输入的课程信息
#             course_num = request.POST.get('course_num')
#             course_name = request.POST.get('course_name')
#             course_teacher = request.POST.get('course_teacher')
#
#             # 验证输入数据
#             if not course_num or not course_name or not course_teacher:
#                 return render(request, 'add_course.html', {
#                     'error_message': '请填写完整的课程信息'
#                 })
#
#             try:
#                 # 尝试查找是否已存在相同的课程
#                 course_obj = None
#                 try:
#                     # 如果输入的课程号是数字，尝试通过课程号查找
#                     course_id = int(course_num)
#                     course_obj = CourseModel.objects.filter(co_num=course_id).first()
#                 except ValueError:
#                     # 如果课程号不是数字，忽略此错误
#                     pass
#
#                 # 如果没有找到课程，通过课程名和教师查找
#                 if not course_obj:
#                     course_obj = CourseModel.objects.filter(co_name=course_name, co_teacher=course_teacher).first()
#
#                 # 如果课程不存在，则创建新课程
#                 if not course_obj:
#                     course_obj = CourseModel.objects.create(
#                         co_name=course_name,
#                         co_teacher=course_teacher
#                     )
#
#                 # 检查是否已经选择了该课程
#                 if not chco.objects.filter(chco_st=student_obj, chco_co=course_obj).exists():
#                     # 创建选课记录
#                     chco.objects.create(chco_st=student_obj, chco_co=course_obj)
#                     # 选课成功，重定向到选课信息页面
#                     return redirect('/course/')
#                 else:
#                     return render(request, 'add_course.html', {
#                         'error_message': '您已选修该课程'
#                     })
#             except Exception as e:
#                 return render(request, 'add_course.html', {
#                     'error_message': '添加课程失败：{}'.format(str(e))
#                 })
#
#         # GET请求，显示添加课程页面
#         return render(request, 'add_course.html')
#
#     except models.student.DoesNotExist:
#         # 如果用户信息不存在，清除会话并重定向到登录页
#         request.session.flush()
#         return redirect('/login')


@csrf_exempt
def edit_course(request, course_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')

    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)

        # 获取要修改的课程
        course_obj = get_object_or_404(CourseModel, pk=course_id)

        # 检查该学生是否选修了这门课程
        if not chco.objects.filter(chco_st=student_obj, chco_co=course_obj).exists():
            return redirect('/course/')

        if request.method == 'POST':
            # 获取用户输入的课程信息
            course_name = request.POST.get('course_name')
            course_teacher = request.POST.get('course_teacher')

            # 验证输入数据
            if not course_name or not course_teacher:
                return render(request, 'edit_course.html', {
                    'course': course_obj,
                    'error_message': '请填写完整的课程信息'
                })

            try:
                # 更新课程信息
                course_obj.co_name = course_name
                course_obj.co_teacher = course_teacher
                course_obj.save()

                # 修改成功，重定向到选课信息页面
                return redirect('/course/')
            except Exception as e:
                return render(request, 'edit_course.html', {
                    'course': course_obj,
                    'error_message': '修改课程失败：{}'.format(str(e))
                })

        # GET请求，显示修改课程页面
        return render(request, 'edit_course.html', {'course': course_obj})

    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


def del_course(request, course_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取要删除的课程
        course_obj = get_object_or_404(CourseModel, pk=course_id)
        
        # 获取选课记录并删除
        try:
            # 先删除选课记录
            choice = chco.objects.get(chco_st=student_obj, chco_co=course_obj)
            choice.delete()
            
        except chco.DoesNotExist:
            # 如果选课记录不存在，尝试直接删除课程
            course_obj.delete()

        return redirect('/course/')
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


@csrf_exempt
def select_course(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')

    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取学生已选课程的ID列表
        selected_course_ids = models.chco.objects.filter(chco_st=student_obj).values_list('chco_co__co_num', flat=True)
        
        # 获取所有课程
        all_courses = models.course.objects.all()
        
        if request.method == 'POST':
            # 获取选中的课程ID
            selected_course_id = request.POST.get('course_id')
            
            if not selected_course_id:
                return render(request, 'select_course.html', {
                    'all_courses': all_courses,
                    'selected_course_ids': selected_course_ids,
                    'error_message': '请选择一门课程'
                })
                
            try:
                # 获取课程对象
                course_obj = CourseModel.objects.get(pk=selected_course_id)
                
                # 检查是否已经选择了该课程
                if not chco.objects.filter(chco_st=student_obj, chco_co=course_obj).exists():
                    # 创建选课记录
                    chco.objects.create(chco_st=student_obj, chco_co=course_obj)
                    # 选课成功，重定向到选课信息页面
                    return redirect('/course/')
                else:
                    return render(request, 'select_course.html', {
                        'all_courses': all_courses,
                        'selected_course_ids': selected_course_ids,
                        'error_message': '您已选修该课程'
                    })
            except Exception as e:
                return render(request, 'select_course.html', {
                    'all_courses': all_courses,
                    'selected_course_ids': selected_course_ids,
                    'error_message': '选课失败：{}'.format(str(e))
                })
        
        # GET请求，显示现有课程列表
        return render(request, 'select_course.html', {
            'all_courses': all_courses,
            'selected_course_ids': selected_course_ids
        })
        
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


@csrf_exempt
def course_manage(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    # 获取所有课程
    all_courses = models.course.objects.all()
    
    return render(request, 'course_manage.html', {
        'all_courses': all_courses
    })


@csrf_exempt
def course_add(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    if request.method == 'POST':
        # 获取用户输入的课程信息
        course_num = request.POST.get('course_num')
        course_name = request.POST.get('course_name')
        course_teacher = request.POST.get('course_teacher')
        
        # 验证输入数据
        if not course_name or not course_teacher:
            return render(request, 'course_add.html', {
                'error_message': '请填写完整的课程信息',
                'course_num': course_num,
                'course_name': course_name,
                'course_teacher': course_teacher
            })
            
        try:
            # 检查是否已存在相同名称和教师的课程
            if CourseModel.objects.filter(co_name=course_name, co_teacher=course_teacher).exists():
                return render(request, 'course_add.html', {
                    'error_message': '该课程已存在',
                    'course_num': course_num,
                    'course_name': course_name,
                    'course_teacher': course_teacher
                })
            
            # 检查课程号是否已存在
            if course_num and CourseModel.objects.filter(co_num=course_num).exists():
                return render(request, 'course_add.html', {
                    'error_message': '该课程号已存在',
                    'course_num': course_num,
                    'course_name': course_name,
                    'course_teacher': course_teacher
                })
                
            # 创建新课程
            if course_num:
                try:
                    course_num = int(course_num)
                    CourseModel.objects.create(
                        co_num=course_num,
                        co_name=course_name,
                        co_teacher=course_teacher
                    )
                except ValueError:
                    return render(request, 'course_add.html', {
                        'error_message': '课程号必须为数字',
                        'course_num': course_num,
                        'course_name': course_name,
                        'course_teacher': course_teacher
                    })
            else:
                CourseModel.objects.create(
                    co_name=course_name,
                    co_teacher=course_teacher
                )
            
            # 添加成功，重定向到课程管理页面
            return redirect('/course_manage/')
        
        except Exception as e:
            return render(request, 'course_add.html', {
                'error_message': '添加课程失败：{}'.format(str(e)),
                'course_num': course_num,
                'course_name': course_name,
                'course_teacher': course_teacher
            })
    
    # GET请求，显示添加课程页面
    return render(request, 'course_add.html')


@csrf_exempt
def course_edit(request, course_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    # 获取要编辑的课程
    course_obj = get_object_or_404(CourseModel, pk=course_id)
    
    if request.method == 'POST':
        # 获取用户输入的课程信息
        course_num = request.POST.get('course_num')
        course_name = request.POST.get('course_name')
        course_teacher = request.POST.get('course_teacher')
        
        # 验证输入数据
        if not course_num or not course_name or not course_teacher:
            return render(request, 'course_edit.html', {
                'course': course_obj,
                'error_message': '请填写完整的课程信息'
            })
            
        try:
            # 检查是否已存在相同名称和教师的其他课程
            if CourseModel.objects.filter(co_name=course_name, co_teacher=course_teacher).exclude(pk=course_id).exists():
                return render(request, 'course_edit.html', {
                    'course': course_obj,
                    'error_message': '已存在相同名称和教师的课程'
                })
                
            # 检查课程号是否已被其他课程使用
            try:
                new_course_num = int(course_num)
                if str(new_course_num) != str(course_id) and CourseModel.objects.filter(co_num=new_course_num).exists():
                    return render(request, 'course_edit.html', {
                        'course': course_obj,
                        'error_message': '该课程号已被其他课程使用'
                    })
            except ValueError:
                return render(request, 'course_edit.html', {
                    'course': course_obj,
                    'error_message': '课程号必须为数字'
                })
                
            # 如果更改了课程号，需要特殊处理
            if str(course_num) != str(course_id):
                # 复制原课程的选课记录
                related_chcos = models.chco.objects.filter(chco_co=course_obj)
                
                # 创建新课程
                new_course = CourseModel.objects.create(
                    co_num=new_course_num,
                    co_name=course_name,
                    co_teacher=course_teacher
                )
                
                # 更新选课记录指向新课程
                for chco_obj in related_chcos:
                    chco_obj.chco_co = new_course
                    chco_obj.save()
                
                # 删除旧课程
                course_obj.delete()
                
                # 更新成功，重定向到课程管理页面
                return redirect('/course_manage/')
            else:
                # 更新课程信息
                course_obj.co_name = course_name
                course_obj.co_teacher = course_teacher
                course_obj.save()
                
                # 更新成功，重定向到课程管理页面
                return redirect('/course_manage/')
        
        except Exception as e:
            return render(request, 'course_edit.html', {
                'course': course_obj,
                'error_message': '修改课程失败：{}'.format(str(e))
            })
    
    # GET请求，显示编辑课程页面
    return render(request, 'course_edit.html', {'course': course_obj})


@csrf_exempt
def course_delete(request, course_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    # 获取要删除的课程
    course_obj = get_object_or_404(CourseModel, pk=course_id)
    
    try:
        # 检查该课程是否已被选修
        if models.chco.objects.filter(chco_co=course_obj).exists():
            # 已被选修，重定向到课程管理页面并显示错误信息
            return redirect('/course_manage/?error=该课程已被学生选修，无法删除')
        
        # 删除课程
        course_obj.delete()
        return redirect('/course_manage/')
    
    except Exception as e:
        # 删除失败，重定向到课程管理页面并显示错误信息
        return redirect('/course_manage/?error=删除课程失败：{}'.format(str(e)))


def mark_info(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取学生的成绩信息
        marks = models.mark.objects.filter(ma_st=student_obj).select_related('ma_xueqi')
        
        return render(request, 'mark.html', {'marks': marks})
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


def money_info(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取学生的消费信息
        moneys = models.money.objects.filter(mo_st=student_obj)
        
        # 计算总消费金额
        total_money = sum(money.mo_money for money in moneys)
        
        return render(request, 'money.html', {
            'moneys': moneys,
            'total_money': total_money
        })
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


def book_info(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取学生的借书信息
        lends = models.lend.objects.filter(le_st=student_obj).select_related('le_bo')
        
        return render(request, 'book.html', {
            'lends': lends,
            'success_message': request.GET.get('success'),
            'error_message': request.GET.get('error')
        })
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


def logout(request):
    # 清除会话数据
    request.session.flush()
    # 重定向到登录页面
    return redirect('/login/')


def all_books(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取所有书籍
        books = models.book.objects.all()
        
        # 获取所有已借阅且未归还的书籍ID列表
        borrowed_book_ids = models.lend.objects.filter(
            le_end=F('le_start')  # 借阅中的书籍(结束时间=开始时间表示尚未归还)
        ).values_list('le_bo__bo_num', flat=True)
        
        return render(request, 'all_books.html', {
            'books': books,
            'borrowed_book_ids': borrowed_book_ids,
            'error_message': request.GET.get('error')
        })
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


@csrf_exempt
def borrow_book(request, book_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取要借阅的书籍
        book_obj = get_object_or_404(models.book, pk=book_id)
        
        # 检查该书是否已被学生借阅且未归还
        if models.lend.objects.filter(le_st=student_obj, le_bo=book_obj, le_end=F('le_start')).exists():
            return redirect('/all_books/?error=您已借阅该书籍，请勿重复借阅')
        
        # 创建借阅记录
        import datetime
        now = datetime.datetime.now()
        models.lend.objects.create(
            le_st=student_obj,
            le_bo=book_obj,
            le_start=now,
            le_end=now  # 初始结束时间与开始时间相同，表示尚未归还
        )
        
        # 借书成功后，直接获取借阅记录并渲染借阅页面
        # 获取学生的借书信息
        lends = models.lend.objects.filter(le_st=student_obj).select_related('le_bo')
        
        return render(request, 'book.html', {
            'lends': lends,
            'success_message': '借阅成功'
        })
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


@csrf_exempt
def return_book(request, book_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取要归还的书籍
        book_obj = get_object_or_404(models.book, pk=book_id)
        
        # 查找借阅记录
        try:
            # 只根据学生和图书查找借阅记录，不考虑借阅状态
            lend_obj = models.lend.objects.filter(
                le_st=student_obj, 
                le_bo=book_obj
            ).order_by('-le_start').first()  # 获取最近的一条借阅记录
            
            if not lend_obj:
                raise models.lend.DoesNotExist("未找到借阅记录")
            
            # 检查是否已经归还（借阅时间和归还时间是否相同）
            if lend_obj.le_start.strftime("%Y%m%d%H%M%S") != lend_obj.le_end.strftime("%Y%m%d%H%M%S"):
                # 已归还
                lends = models.lend.objects.filter(le_st=student_obj).select_related('le_bo')
                return render(request, 'book.html', {
                    'lends': lends,
                    'error_message': f'《{book_obj.bo_name}》已经归还过了'
                })
            
            # 直接使用当前时间作为归还时间
            import datetime
            lend_obj.le_end = datetime.datetime.now() + datetime.timedelta(seconds=1)
            
            # 保存更新后的借阅记录
            lend_obj.save()
            
            # 归还成功后，直接获取借阅记录并渲染借阅页面
            lends = models.lend.objects.filter(le_st=student_obj).select_related('le_bo')
            
            return render(request, 'book.html', {
                'lends': lends,
                'success_message': '归还成功'
            })
            
        except models.lend.DoesNotExist:
            # 如果没有找到对应的借阅记录，直接获取所有借阅记录并返回借阅页面
            lends = models.lend.objects.filter(le_st=student_obj).select_related('le_bo')
            
            return render(request, 'book.html', {
                'lends': lends,
                'error_message': f'未找到《{book_obj.bo_name}》的借阅记录'
            })
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


@csrf_exempt
def add_book(request):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        if request.method == 'POST':
            # 获取表单数据
            book_num = request.POST.get('book_num')
            book_name = request.POST.get('book_name')
            
            if not book_name:
                return render(request, 'add_book.html', {
                    'error_message': '书名不能为空'
                })
            
            try:
                # 检查书号是否已存在
                if book_num:
                    if models.book.objects.filter(bo_num=book_num).exists():
                        return render(request, 'add_book.html', {
                            'error_message': f'书号 {book_num} 已存在',
                            'book_name': book_name
                        })
                    # 创建指定书号的图书
                    models.book.objects.create(
                        bo_num=book_num,
                        bo_name=book_name
                    )
                else:
                    # 不指定书号，自动生成
                    models.book.objects.create(
                        bo_name=book_name
                    )
                
                # 重定向到所有书籍页面并显示成功消息
                return redirect('/all_books/?success=图书添加成功')
            except Exception as e:
                return render(request, 'add_book.html', {
                    'error_message': f'添加图书失败: {str(e)}',
                    'book_name': book_name,
                    'book_num': book_num
                })
        else:
            # GET请求，显示添加图书表单
            return render(request, 'add_book.html', {})
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


def mark(request):
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生的学号
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取该学生的所有成绩记录，使用正确的字段名 ma_st
        marks = models.mark.objects.filter(ma_st=student_obj).order_by('ma_xueqi__te_name')
        
        # 计算平均分
        if marks:
            avg_mark = sum(float(mark.ma_mark) for mark in marks) / len(marks)
        else:
            avg_mark = 0
        
        return render(request, 'mark.html', {
            'marks': marks,
            'avg_mark': avg_mark
        })
        
    except models.student.DoesNotExist:
        request.session.flush()
        return redirect('/login')


class MarkChartView(APIView):
    def get(self, request, *args, **kwargs):
        # 打印请求信息，便于调试
        print("Chart API被调用")
        
        if not request.session.get('is_authenticated'):
            print("用户未登录")
            return JsonResponse({
                'code': 403,
                'msg': '未登录',
                'data': {}
            })
        
        try:
            # 获取当前登录学生的学号
            username = request.session.get('username')
            print(f"当前学生学号: {username}")
            
            student_obj = models.student.objects.get(pk=username)
            
            # 获取该学生的所有成绩记录
            marks = models.mark.objects.filter(ma_st=student_obj).order_by('ma_xueqi__te_name')
            print(f"找到成绩记录数: {marks.count()}")
            
            if marks:
                # 准备数据
                x_data = [mark.ma_xueqi.te_name for mark in marks]
                y_data = [float(mark.ma_mark) for mark in marks]
                
                # print(f"X轴数据: {x_data}")
                # print(f"Y轴数据: {y_data}")
                
                # 计算平均分
                avg_mark = sum(y_data) / len(y_data)
                
                # 创建图表实例
                line = Line()
                line.add_xaxis(x_data)
                line.add_yaxis(
                    "成绩",
                    y_data,
                    is_smooth=True,
                    label_opts=opts.LabelOpts(is_show=True),
                    markpoint_opts=opts.MarkPointOpts(
                        data=[]
                    ),
                    markline_opts=opts.MarkLineOpts(
                        data=[
                            opts.MarkLineItem(type_="average", name="平均分"),
                            opts.MarkLineItem(y=60, name="及格线")
                        ]
                    )
                )
                
                # 设置全局选项
                line.set_global_opts(
                    title_opts=opts.TitleOpts(
                        # title="成绩趋势图",
                        subtitle=f"平均分: {avg_mark:.1f}分"
                    ),
                    tooltip_opts=opts.TooltipOpts(trigger="axis"),
                    toolbox_opts=opts.ToolboxOpts(is_show=True),
                    xaxis_opts=opts.AxisOpts(
                        type_="category",
                        name="学期",
                        axislabel_opts=opts.LabelOpts(rotate=45)
                    ),
                    yaxis_opts=opts.AxisOpts(
                        type_="value",
                        name="成绩",
                        min_=0,
                        max_=100,
                        interval=10,
                        axislabel_opts=opts.LabelOpts(formatter="{value}分")
                    )
                )
                
                # 转为JSON数据
                chart_json = line.dump_options_with_quotes()
                data = json.loads(chart_json)
                
                # print("生成图表数据成功")
                
                # 返回图表数据
                response = JsonResponse({
                    'code': 200,
                    'msg': 'success',
                    'data': data
                })
                
                # 允许跨域
                response["Access-Control-Allow-Origin"] = "*"
                return response
            else:
                print("没有找到成绩记录")
                return JsonResponse({
                    'code': 404,
                    'msg': '暂无成绩数据',
                    'data': {}
                })
                
        except models.student.DoesNotExist:
            print(f"学生 {username} 不存在")
            return JsonResponse({
                'code': 404,
                'msg': '学生信息不存在',
                'data': {}
            })
        except Exception as e:
            print(f"发生错误: {str(e)}")
            import traceback
            traceback.print_exc()
            return JsonResponse({
                'code': 500,
                'msg': str(e),
                'data': {}
            })


class MoneyChartView(APIView):
    def get(self, request, *args, **kwargs):
        # 打印请求信息，便于调试
        print("Money Chart API被调用")
        
        if not request.session.get('is_authenticated'):
            print("用户未登录")
            return JsonResponse({
                'code': 403,
                'msg': '未登录',
                'data': {}
            })
        
        try:
            # 获取当前登录学生的学号
            username = request.session.get('username')
            print(f"当前学生学号: {username}")
            
            student_obj = models.student.objects.get(pk=username)
            
            # 获取该学生的所有消费记录
            moneys = models.money.objects.filter(mo_st=student_obj).order_by('mo_month')
            print(f"找到消费记录数: {moneys.count()}")
            
            if moneys:
                # 准备数据
                x_data = [f"{money.mo_month}月" for money in moneys]
                y_data = [float(money.mo_money) for money in moneys]
                
                # print(f"X轴数据: {x_data}")
                # print(f"Y轴数据: {y_data}")
                
                # 计算平均消费
                avg_money = sum(y_data) / len(y_data)
                total_money = sum(y_data)
                
                # 创建图表实例

                bar = Bar()
                bar.add_xaxis(x_data)
                bar.add_yaxis(
                    "消费金额",
                    y_data,
                    label_opts=opts.LabelOpts(is_show=True, formatter="{c} 元"),
                    markline_opts=opts.MarkLineOpts(
                        data=[
                            opts.MarkLineItem(type_="average", name="月均消费")
                        ]
                    )
                )
                
                # 设置全局选项
                bar.set_global_opts(
                    title_opts=opts.TitleOpts(
                        # title="月度消费统计图",
                        # subtitle=f"总消费: {total_money:.1f}元，月均: {avg_money:.1f}元"
                        subtitle=f"总消费: {total_money:.1f}元，月均: {avg_money:.1f}元"
                    ),
                    tooltip_opts=opts.TooltipOpts(trigger="axis"),
                    toolbox_opts=opts.ToolboxOpts(is_show=True),
                    xaxis_opts=opts.AxisOpts(
                        type_="category",
                        name="月份",
                        axislabel_opts=opts.LabelOpts(rotate=45)
                    ),
                    yaxis_opts=opts.AxisOpts(
                        type_="value",
                        name="金额",
                        axislabel_opts=opts.LabelOpts(formatter="{value} 元")
                    )
                )
                
                # 转为JSON数据
                chart_json = bar.dump_options_with_quotes()
                data = json.loads(chart_json)
                
                # print("生成图表数据成功")
                
                # 返回图表数据
                response = JsonResponse({
                    'code': 200,
                    'msg': 'success',
                    'data': data
                })
                
                # 允许跨域
                response["Access-Control-Allow-Origin"] = "*"
                return response
            else:
                print("没有找到消费记录")
                return JsonResponse({
                    'code': 404,
                    'msg': '暂无消费数据',
                    'data': {}
                })
                
        except models.student.DoesNotExist:
            print(f"学生 {username} 不存在")
            return JsonResponse({
                'code': 404,
                'msg': '学生信息不存在',
                'data': {}
            })
        except Exception as e:
            print(f"发生错误: {str(e)}")
            import traceback
            traceback.print_exc()
            return JsonResponse({
                'code': 500,
                'msg': str(e),
                'data': {}
            })


@csrf_exempt
def edit_book(request, book_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取要修改的图书
        try:
            book_obj = models.book.objects.get(pk=book_id)
        except models.book.DoesNotExist:
            return redirect('/all_books/?error=图书不存在')
        
        if request.method == 'POST':
            # 获取表单数据
            book_name = request.POST.get('book_name')
            
            if not book_name:
                return render(request, 'edit_book.html', {
                    'book': book_obj,
                    'error_message': '书名不能为空'
                })
            
            # 检查是否有其他图书使用了相同书名
            if models.book.objects.filter(bo_name=book_name).exclude(pk=book_id).exists():
                return render(request, 'edit_book.html', {
                    'book': book_obj,
                    'error_message': f'已存在书名为 {book_name} 的图书'
                })
            
            # 更新图书信息
            book_obj.bo_name = book_name
            book_obj.save()
            
            # 重定向到所有图书页面并显示成功消息
            return redirect('/all_books/?success=图书修改成功')
        else:
            # GET请求，显示修改表单
            return render(request, 'edit_book.html', {
                'book': book_obj
            })
    
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


@csrf_exempt
def delete_book(request, book_id):
    # 检查用户是否已登录
    if not request.session.get('is_authenticated'):
        return redirect('/login')
    
    try:
        # 获取当前登录学生信息
        username = request.session.get('username')
        student_obj = models.student.objects.get(pk=username)
        
        # 获取要删除的图书
        book_obj = get_object_or_404(models.book, pk=book_id)
        
        try:
            # 检查该图书是否有未归还的借阅记录
            if models.lend.objects.filter(le_bo=book_obj, le_end=F('le_start')).exists():
                # 有未归还的借阅记录，重定向到图书管理页面并显示错误信息
                return redirect('/all_books/?error=该图书有未归还的借阅记录，无法删除')
            
            # 删除图书
            book_obj.delete()
            return redirect('/all_books/?success=图书删除成功')
        
        except Exception as e:
            # 删除失败，重定向到图书管理页面并显示错误信息
            return redirect(f'/all_books/?error=删除图书失败：{str(e)}')
        
    except models.student.DoesNotExist:
        # 如果用户信息不存在，清除会话并重定向到登录页
        request.session.flush()
        return redirect('/login')


class BookChartView(APIView):
    def get(self, request, *args, **kwargs):
        # 打印请求信息，便于调试
        print("Book Chart API被调用")
        
        if not request.session.get('is_authenticated'):
            print("用户未登录")
            return JsonResponse({
                'code': 403,
                'msg': '未登录',
                'data': {}
            })
        
        try:
            # 获取当前登录学生的学号
            username = request.session.get('username')
            print(f"当前学生学号: {username}")
            
            student_obj = models.student.objects.get(pk=username)
            
            # 执行查询，统计当前用户借阅的每本书的借阅次数
            from django.db.models import Count
            book_borrow_stats = models.lend.objects.filter(
                le_st=student_obj  # 只统计当前用户
            ).values('le_bo__bo_name').annotate(
                borrow_count=Count('le_bo')
            ).order_by('-borrow_count')[:10]  # 获取前10本借阅次数最多的书
            
            print(f"找到用户借阅统计记录数: {book_borrow_stats.count()}")
            
            if book_borrow_stats:
                # 准备数据
                book_names = [item['le_bo__bo_name'] for item in book_borrow_stats]
                borrow_counts = [item['borrow_count'] for item in book_borrow_stats]
                
                return JsonResponse({
                    'code': 200,
                    'msg': 'success',
                    'data': {
                        'xAxis': {
                            'type': 'category',
                            'data': book_names
                        },
                        'yAxis': {
                            'type': 'value'
                        },
                        'series': [
                            {
                                'name': '借阅次数',
                                'type': 'bar',
                                'data': borrow_counts
                            }
                        ]
                    }
                })
            else:
                print("没有找到借阅记录")
                return JsonResponse({
                    'code': 404,
                    'msg': '暂无借阅数据',
                    'data': {}
                })
                
        except models.student.DoesNotExist:
            print(f"学生 {username} 不存在")
            return JsonResponse({
                'code': 404,
                'msg': '学生信息不存在',
                'data': {}
            })
        except Exception as e:
            print(f"发生错误: {str(e)}")
            import traceback
            traceback.print_exc()
            return JsonResponse({
                'code': 500,
                'msg': str(e),
                'data': {}
            })


